function xdot = swerveEOM(x,t)
% different input arguments order for MATLAB vs. Octave
if usingOctave == 0
    temp = t;
    t = x;
    x = temp;
    clear temp;
end

% define empty output vector
xdot = zeros(size(x'));

stateDfn; % get state definitions
robotSetup; % setup robot, get important constants

% generate rotation matrices
% [vector in e] = lea * [vector in a]
lea = [cos(x(STH)) -sin(x(STH)) 0; sin(x(STH)) cos(x(STH)) 0; 0 0 1];
lae = lea';

% get/calculate joystick values
joy = joystickInput(x,t);

% use joystick values to calculate motor commands (desired speed vectors)
commands = driveCode(x, t, robot, joy);

% calculate applied voltages to drive + turn motors
voltages = commandVoltages(x, t, robot, commands);

driveForces = [0; 0; 0];
driveMoments = [0; 0; 0]; % vector so vector math works nicely

gearRatio = 10; % gear ratio % TODO more useful!

speeds = wheelSpeeds(x,t,robot); % calculate linear speed of each wheel

% DRIVE MOTORS (for each...)
for i = 1:robot.modules
	% TODO move some of these calculations to functions to allow intermediate values to be calculated after the simulation is complete
	% calculate motor speed (using robot speed)
	wMotor = speeds(i)*gearRatio/robot.wheelR;

	% electrical response (depends upon motor speed)
	xdot(SI + modS*(i-1)) = (voltages.drive(i) - x(SI + modS*(i-1))*robot.drive.R - robot.drive.kEMF*wMotor)/robot.drive.L;

	% calculate applied motor torque (apply efficiency factor)
	motorTorque = x(SI + modS*(i-1))*robot.drive.kT*robot.drive.eta;

	% calculate appplied force from each wheel
	wheelForce = gearRatio * motorTorque / robot.wheelR; % force scalar % TODO transmission
	wheelForceA = [wheelForce*cos(x(SPHI + modS*(i-1))); wheelForce*sin(x(SPHI + modS*(i-1))); 0]; % vector in A
	wheelForceE = lea*wheelForceA; % vector in E (inertial)
	driveForces = driveForces + wheelForceE;

	% calculate applied moment from each wheel M = r X F
	wheelMoment = cross(robot.module(i).loc , wheelForceA); % TODO compensate for cm/gc offset?
	driveMoments = driveMoments + wheelMoment;
end
	

% ROBOT EOMS
% rotational EOM
xdot(STH) = x(SDTH); % angular velocity
xdot(SDTH) = driveMoments(3) / robot.I(3,3); % angular acceleration % TODO check no addtl terms needed

% translational EOMs
xdot(SX) = x(SDX); % x-velocity (inertial)
xdot(SY) = x(SDY); % y-velocity (inertial)
xdot(SDX) = driveForces(1)/robot.mass; % x-acceleration (inertial) % TODO add cm variance terms
xdot(SDY) = driveForces(2)/robot.mass; % y-acceleration (inertial) % TODO add cm variance terms

% ROTATION MOTORS (for each...)

% MODULE EOMS
for i=1:robot.modules
	xdot(SPHI+modS*(i-1)) = 0.5;
end

% more differences
if usingOctave() == 0
    xdot = xdot';
end

return
